﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.NetworkInformation;
using OrbitOne.Elmah.Data;

namespace OrbitOne.Elmah.Logic
{
    /// <summary>
    /// Represents an agent service.
    /// </summary>
    public class AgentService : ElmahService<Data.Agent>
    {

        #region Constructor
        /// <summary>
        /// Creates a new agent service.
        /// </summary>
        public AgentService()
        {

        }

        /// <summary>
        /// Creates a new agent service based on the specified <code>IElmahDataProvider</code>
        /// </summary>
        /// <param name="provider">The data provider to use.</param>
        public AgentService(ElmahDataProvider provider)
        {
            this.Provider = provider;
        }
        #endregion

        #region Public Methods
        /*/// <summary>
        /// Get an agent entity by name
        /// </summary>
        /// <param name="name">The name of the agent entity you want to get.</param>
        /// <returns>The first agent entity that qualifies or null if no agent entity is found.</returns>
        public AgentEntity GetByName(string name)
        {
            return GetAll().Where(agent => agent.Name == name).FirstOrDefault();
        }*/

        /// <summary>
        /// Get an agent entity by the date and time it was created on.
        /// </summary>
        /// <param name="creationDate">Date the agent was installed</param>
        /// <param name="agentName">name of the agent</param>
        /// <returns></returns>
        public Data.Agent GetByCreatedOn(DateTime creationDate, string agentName)
        {
            return Provider.Context.Agents.Where(agent => agent.CreatedOn == creationDate && agent.Name == agentName).FirstOrDefault();
        }
        
        /// <summary>
        /// Get all the agents with there status. (alive or dead)
        /// </summary>
        /// <param name="deathHeartbeats">The nr of heartbeats that can be skipped before an agent is declared dead.(default is 6)</param>
        /// <param name="hearthbeatInterval">The nr of milliseconds between each heartbeat. (default is 300000)</param>
        /// <returns><code>IList:Agent</code></returns>
        public IList<Agent> GetAllAgents(int? deathHeartbeats, int? hearthbeatInterval)
        {
            if (!deathHeartbeats.HasValue) deathHeartbeats = 6;
            if (!hearthbeatInterval.HasValue) hearthbeatInterval = 30000;

            return Provider.Context.Agents
                .Select(agent =>
                        new Agent(agent.Name,
                                  agent.Description,
                                  agent.LastHeartBeat,
                                  agent.CreatedOn,
                                  (DateTime.Now - agent.LastHeartBeat).TotalMilliseconds < deathHeartbeats * hearthbeatInterval))
                .ToList();
        }

        public void Save(Data.Agent agent)
        {
            if (!Provider.Context.Agents.Contains(agent))
            {
                Provider.Context.Agents.InsertOnSubmit(agent);
            }
            Provider.Context.SubmitChanges();
        }
        #endregion
    }
}